package cn.tedu.charging.order.mqtt;

import cn.tedu.charging.common.consts.ChargingReResult;
import cn.tedu.charging.common.consts.OrderStatus;
import cn.tedu.charging.common.consts.TopicNameStatus;
import cn.tedu.charging.common.pojo.param.ChargingProcessParam;
import cn.tedu.charging.common.pojo.vo.ChargingProcessVO;
import cn.tedu.charging.common.result.JsonResult;
import cn.tedu.charging.common.utils.JsonUtil;
import cn.tedu.charging.order.dao.repository.ChargingProcessESRepository;
import cn.tedu.charging.order.feign.CostClient;
import cn.tedu.charging.order.pojo.dto.ChargingProcessDto;
import cn.tedu.charging.order.pojo.dto.ChargingResultDto;
import cn.tedu.charging.order.pojo.po.ChargingBillFailPo;
import cn.tedu.charging.order.pojo.po.ChargingBillSuccessPo;
import cn.tedu.charging.order.pojo.po.ChargingProcessESPO;
import cn.tedu.charging.order.pojo.po.RabbitmqDeadPo;
import cn.tedu.charging.order.websocket.WebSocketServer;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.*;
import org.springframework.beans.BeanUtils;

import java.util.Collection;
import java.util.Collections;


@Slf4j
public class MqttConsumer implements MqttCallbackExtended {


    private MqttClient mqttClient;
    private MqttContext mqttContext;

    public MqttConsumer(MqttClient mqttClient,MqttContext mqttContext){
        this.mqttClient=mqttClient;
        this.mqttContext=mqttContext;
    }



    @Override
    public void connectionLost(Throwable throwable) {

    }

    @Override
    public void messageArrived(String topic, MqttMessage mqttMessage) throws Exception {
        log.debug("消息已到达 topic={} mqttMessage={}",topic,mqttMessage);
        
        if (TopicNameStatus.TOPIC_CHARGING_RESULT.equals(topic)){
            log.debug("开始处理 result");
            handReResult(mqttMessage);
        }else if (TopicNameStatus.TOPIC_CHARGING_PROCESS.equals(topic)){
            log.debug("开始处理 process");
            handReProcess(mqttMessage);
        }



    }


    private void handReProcess(MqttMessage mqttMessage){
        String str = mqttMessage.toString();
        ChargingProcessDto chargingProcessDto = null;
        try {
            chargingProcessDto = JsonUtil.toObject(str,ChargingProcessDto.class);
            //保存充电数据
            saveChargingProcessVO(chargingProcessDto);
        } catch (Exception e) {
            log.debug("传入的数据json格式有误！");
            return;
        }

        CostClient costClient = mqttContext.getCostClient();
        ChargingProcessParam  chargingProcessParam = new ChargingProcessParam();
        BeanUtils.copyProperties(chargingProcessDto,chargingProcessParam);
        log.debug("调用计价服务入参 chargingProcessParam={}",chargingProcessParam);
        JsonResult<ChargingProcessVO> chargingProcessVoJsonResult = costClient.cacleChargingPrice(chargingProcessParam);
        log.debug("调用计价服务入参 chargingProcessParam={} 返回结果={}",chargingProcessParam,chargingProcessVoJsonResult);
        //发送消息给用户
        sendMsg2User(chargingProcessDto.getUserId(),chargingProcessVoJsonResult.getData());

    }

    private void sendMsg2User(Integer userId,ChargingProcessVO data) {
        WebSocketServer webSocketServer = mqttContext.getWebSocketServer();
        //发送消息给用户
        webSocketServer.sendMessage(userId,JsonUtil.toJson(data));
        log.debug("已同步数据给用户！");
    }

    private void handReResult(MqttMessage mqttMessage) {
        String str= mqttMessage.toString();
        ChargingResultDto chargingResultDto = null;
        try {
            chargingResultDto = JsonUtil.toObject(str, ChargingResultDto.class);
        } catch (Exception e) {
            log.debug("传入的数据json格式有误！");
            return;
        }
        if (ChargingReResult.START_SUCCESS.equals(chargingResultDto.getResult())){
            log.debug("生成成功订单");
            //向队列发送消息 开始倒计时
            RabbitmqDeadPo rabbitmqDeadPo = new RabbitmqDeadPo();
            rabbitmqDeadPo.setOrderNo(chargingResultDto.getOrderNo());
            mqttContext.getRabbitMQProducter().sendMsg(rabbitmqDeadPo);
            log.debug("已开始倒计时！");

            //生成订单
            ChargingBillSuccessPo chargingBillSuccessPo = new ChargingBillSuccessPo();
            chargingBillSuccessPo.setBillId(chargingResultDto.getOrderNo());
            chargingBillSuccessPo.setBillStatus(OrderStatus.CHARGING_ING);
            int i = mqttContext.getChargingBillSuccessMapper().insert(chargingBillSuccessPo);
            if (i==1){
                log.debug("插入订单成功");
            }

        }else if(ChargingReResult.STOP_SUCCESS.equals(chargingResultDto.getResult())){
            log.debug("订单准备结束，已停止充电");
            log.debug("修改订单状态");
            ChargingBillSuccessPo chargingBillSuccessPo = new ChargingBillSuccessPo();
            chargingBillSuccessPo.setBillId(chargingResultDto.getOrderNo());
            chargingBillSuccessPo.setBillStatus(OrderStatus.CHARGING_COMPLETION);
            int i = mqttContext.getChargingBillSuccessMapper().updateById(chargingBillSuccessPo);
            if (i==1){
                log.debug("更新订单成功");
            }
        }else {
            log.debug("设备有响应，但是处理失败，准备通知用户使用其他设备，并且通知管理员修复设备");
            log.debug("生成失败订单");
            ChargingBillFailPo chargingBillFailPo = new ChargingBillFailPo();
            chargingBillFailPo.setBillId(chargingResultDto.getOrderNo());
            chargingBillFailPo.setFailDesc("失败就是失败了");
            int i = mqttContext.getChargingBillFailMapper().insert(chargingBillFailPo);
            if (i==1){
                log.debug("插入失败订单成功");
            }
        }
    }

    private void saveChargingProcessVO(ChargingProcessDto chargingProcessDto) {
        ChargingProcessESPO chargingProcessESPO = new ChargingProcessESPO();
        BeanUtils.copyProperties(chargingProcessDto, chargingProcessESPO);
        chargingProcessESPO.setId(System.currentTimeMillis());
        ChargingProcessESRepository chargingProcessESRepository = mqttContext.getChargingProcessESRepository();
        //保存到ES
        chargingProcessESRepository.save(chargingProcessESPO);
    }

    @Override
    public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {

    }

    @Override
    public void connectComplete(boolean b, String s) {
        log.debug("已连接到eqmx服务器！b={} s={}",b,s);

        try {
            this.mqttClient.subscribe(TopicNameStatus.TOPIC_CHARGING_RESULT);
            this.mqttClient.subscribe(TopicNameStatus.TOPIC_CHARGING_PROCESS);
            log.debug("连接成功,成功订阅开始充电指令结果 topic:{},",TopicNameStatus.TOPIC_CHARGING_RESULT);
            log.debug("连接成功,成功订阅开始充电指令结果 topic:{},",TopicNameStatus.TOPIC_CHARGING_PROCESS);
        } catch (MqttException e) {
            throw new RuntimeException(e);
        }
    }
}
